﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;

namespace PasteCluster
{

    /// <summary>
    /// 
    /// </summary>
    [ApiController]
    [Route("/api/cluster/[action]")]
    public class PasteClusterController : Controller
    {

        private PasteClusterHandler _handler;
        private PasteSloveConfig _config;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="config"></param>
        public PasteClusterController(PasteClusterHandler handler, IOptions<PasteSloveConfig> config)
        {
            _config = config.Value;
            _handler = handler;
        }

        /// <summary>
        /// 健康检查
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public PasteApiResponse health()
        {
            CheckHeader();
            return _handler.Health();
        }

        /// <summary>
        /// 健康检查 节点链接master检查
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> link(PasteNodeModel input)
        {
            CheckHeader();
            return await _handler.Link(input);
        }

        /// <summary>
        /// 读取当前状态
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public string status()
        {
            return _handler.Status();
        }

        /// <summary>
        /// 问询master信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<PasteApiResponse> ask()
        {
            CheckHeader();
            return await _handler.Ask();
        }

        /// <summary>
        /// 有节点要求我群发 群发我是master的信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<PasteApiResponse> broad()
        {
            CheckHeader();
            
            return await _handler.Broad();
        }

        /// <summary>
        /// 查找自己
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> find(PasteNodeModel input)
        {
            CheckHeader();
            return await _handler.Find(input);
        }

        /// <summary>
        /// 有节点加入
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public PasteApiResponse join(PasteNodeModel input)
        {
            CheckHeader();
            _handler.Join(input);
            return _handler.State();
        }

        /// <summary>
        /// 转发消息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> msg(PasteSloveMessage input)
        {
            CheckHeader();
            input.from_api = true;
            return await _handler.Msg(input);
        }

        /// <summary>
        /// 往集群中发送消息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public PasteApiResponse push(PasteSloveMessage input)
        {
            CheckHeader();
            _handler.PushMsgToNode(input.body);
            return _handler.State();
        }

        /// <summary>
        /// 这个一般是PasteSpider推送过来的信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public PasteApiResponse run()
        {
            JObject info = null;
            if (base.Request.Body != null)
            {
                if (base.Request.Body != null)
                {
                    using var stream = new StreamReader(base.Request.Body);
                    var bodystr = stream.ReadToEndAsync().GetAwaiter().GetResult();
                    //Console.WriteLine(bodystr);
                    info = Newtonsoft.Json.JsonConvert.DeserializeObject<JObject>(bodystr);
                }
            }
            if (info != null)
            {
                var _host = string.Empty;
                var _port = 80;
                JObject input = info;
                //if(info is JObject)
                //{
                //    input = input as JObject;
                //}
                //else
                //{
                //    Console.WriteLine("input is not JContainer");
                //    return _handler.State();
                //}
                if (input.ContainsKey("proAddress"))
                {
                    _host = input["proAddress"].ToString();
                }
                if (input.ContainsKey("extendService"))
                {
                    var _ser = input["extendService"];
                    if (_ser.Type == JTokenType.Object)
                    {
                        var _serobj = _ser as JObject;
                        if (_serobj.ContainsKey("listenPorts"))
                        {
                            var ports = _serobj["listenPorts"].ToString();
                            if (!String.IsNullOrEmpty(ports))
                            {
                                int.TryParse(ports.Split(',')[0], out var _pp);
                                if (_pp > 0)
                                {
                                    _port = _pp;
                                }
                            }
                        }
                    }
                }
                if (!String.IsNullOrEmpty(_host))
                {
                    if (_port != 80)
                    {
                        _handler.Register($"http://{_host}:{_port}", 0, 0);
                    }
                    else
                    {
                        _handler.Register($"http://{_host}", 0, 0);
                    }
                }
                else
                {
                    //Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(input));
                }
            }
            return _handler.State();
        }

        /// <summary>
        /// 手动注册自己
        /// </summary>
        /// <param name="input"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpGet]
        public string joinin([FromQuery] PasteNodeModel input, string token)
        {
            if (token == _config.SloveToken)
            {
                _handler.Register(input.host, input.id, input.group);
            }
            else
            {
                return "token参数错误！";
            }
            return "手动加入！";
        }

        /// <summary>
        /// 加入某一个节点，当前需要为master
        /// </summary>
        /// <param name="input"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpGet]
        public string addone([FromQuery] PasteNodeModel input, string token)
        {
            if (token == _config.SloveToken)
            {
                if (_handler.CurrentIsMaster || _handler.IsSingle)
                {
                    var node = new PasteNodeModel
                    {
                        host = input.host,
                        id = input.id,
                        group = input.group,

                    };
                     _handler.AddNodeToList(node);
                }
                else
                {
                    return "当前节点不是Master，无法执行这个命令";
                }
            }
            else
            {
                return "token参数错误！";
            }
            return "手动加入！";
        }

        /// <summary>
        /// 节点集合
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public PasteNodeModel[] nodes()
        {
            return _handler.Nodes();
        }

        /// <summary>
        /// 执行选举
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> vote(PasteNodeModel input)
        {
            CheckHeader();
            return await _handler.Vote(input);
        }

        /// <summary>
        /// 被通知，有成为master
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> master(PasteMasterResponse input)
        {
            CheckHeader();
            //Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(input));
            return await _handler.Master(input);
        }

        /// <summary>
        /// 有节点离开
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> leave(PasteNodeModel input)
        {
            CheckHeader();
            return await _handler.Leave(input);
        }

        /// <summary>
        /// 移除某节点
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PasteApiResponse> remove(PasteNodeModel input)
        {
            CheckHeader();
            return await _handler.Remove(input);
        }

        /// <summary>
        /// 检查信息是否合法
        /// </summary>
        /// <exception cref="Exception"></exception>
        private void CheckHeader()
        {
            if (base.Request.Headers.ContainsKey("slovetoken"))
            {
                if (base.Request.Headers["slovetoken"] != _config.SloveToken)
                {
                    throw new Exception("slovetoken错误，请重新输入！");
                }
                else
                {
                    if (base.Request.Headers.ContainsKey("fromnode"))
                    {
                        _handler.TargetMasterLast(base.Request.Headers["fromnode"].ToString());
                    }
                    if (base.Request.Headers.ContainsKey("masternode"))
                    {
                        _handler.ConfirmMaster(base.Request.Headers["masternode"].ToString());
                    }
                }
            }
            else
            {
                throw new Exception("slovetoken不能为空，请重新输入！");
            }
        }

    }
}
